`include "define.v"
// Y86 register file: 2W2R, 1T write, 0T read
module regFile (
    /*AUTOARG*/
   // Outputs
   d_rvalA, d_rvalB,
   // Inputs
   clock, reset, d_srcA, d_srcB, w_dstE, w_dstM, w_valE, w_valM
   );

input           clock;
input           reset;
input   [3:0]   d_srcA;
input   [3:0]   d_srcB;
output  [31:0]  d_rvalA;
output  [31:0]  d_rvalB;
input   [3:0]   w_dstE;
input   [3:0]   w_dstM;
input   [31:0]  w_valE;
input   [31:0]  w_valM;

/*AUTOWIRE*/
/*AUTOREG*/

reg [31:0] eax, ecx, edx, ebx, esp, ebp, esi, edi;
// read logic
assign d_rvalA = 
              (d_srcA == `REAX) ? eax :
              (d_srcA == `RECX) ? ecx :
              (d_srcA == `REDX) ? edx :
              (d_srcA == `REBX) ? ebx :
              (d_srcA == `RESP) ? esp :
              (d_srcA == `REBP) ? ebp :
              (d_srcA == `RESI) ? esi :
              (d_srcA == `REDI) ? edi :
              32'h0000_0000;

assign d_rvalB = 
              (d_srcB == `REAX) ? eax :
              (d_srcB == `RECX) ? ecx :
              (d_srcB == `REDX) ? edx :
              (d_srcB == `REBX) ? ebx :
              (d_srcB == `RESP) ? esp :
              (d_srcB == `REBP) ? ebp :
              (d_srcB == `RESI) ? esi :
              (d_srcB == `REDI) ? edi :
              32'h0000_0000;

// write logic
//`REAX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        eax <= 32'h0000_0000;
    end else if(w_dstE == `REAX || w_dstM == `REAX) begin
        eax <= (w_dstM == `REAX) ? w_valM : w_valE;
    end
end

//`RECX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        ecx <= 32'h0000_0000;
    end else if(w_dstE == `RECX || w_dstM == `RECX) begin
        ecx <= (w_dstM == `RECX) ? w_valM : w_valE;
    end
end

//`REDX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        edx <= 32'h0000_0000;
    end else if(w_dstE == `REDX || w_dstM == `REDX) begin
        edx <= (w_dstM == `REDX) ? w_valM : w_valE;
    end
end

//`REBX
always @(posedge clock, posedge reset) begin
    if(reset)begin
        ebx <= 32'h0000_0000;
    end else if(w_dstE == `REBX || w_dstM == `REBX) begin
        ebx <= (w_dstM == `REBX) ? w_valM : w_valE;
    end
end

//`RESP
always @(posedge clock, posedge reset) begin
    if(reset)begin
        esp <= 32'h0000_0000;
    end else if(w_dstE == `RESP || w_dstM == `RESP) begin
        esp <= (w_dstM == `RESP) ? w_valM : w_valE;
    end
end

//`REBP
always @(posedge clock, posedge reset) begin
    if(reset)begin
        ebp <= 32'h0000_0000;
    end else if(w_dstE == `REBP || w_dstM == `REBP) begin
        ebp <= (w_dstM == `REBP) ? w_valM : w_valE;
    end
end

//`RESI
always @(posedge clock, posedge reset) begin
    if(reset)begin
        esi <= 32'h0000_0000;
    end else if(w_dstE == `RESI || w_dstM == `RESI) begin
        esi <= (w_dstM == `RESI) ? w_valM : w_valE;
    end
end

//`REDI
always @(posedge clock, posedge reset) begin
    if(reset)begin
        edi <= 32'h0000_0000;
    end else if(w_dstE == `REDI || w_dstM == `REDI) begin
        edi <= (w_dstM == `REDI) ? w_valM : w_valE;
    end
end

endmodule

